MODULE_NAME='Sony_STR-DA7ES'
(
  Dev dvRcvr,
  Dev vdvRcvr
)

(*{{PS_SOURCE_INFO(PROGRAM STATS)                          *)
(***********************************************************)
(*  FILE CREATED ON: 09/18/2002 AT: 16:30:00               *)
(***********************************************************)
(*  FILE_LAST_MODIFIED_ON: 04/09/2003 AT: 16:11:22         *)
(***********************************************************)
(*  ORPHAN_FILE_PLATFORM: 1                                *)
(***********************************************************)
(*!!FILE REVISION: Rev 0                                   *)
(*  REVISION DATE: 03/30/2003                              *)
(*                                                         *)
(*  COMMENTS:                                              *)
(*                                                         *)
(***********************************************************)
(*!!FILE REVISION: Rev 0                                   *)
(*  REVISION DATE: 10/02/2002                              *)
(*                                                         *)
(*  COMMENTS:                                              *)
(*    Written by: Steve Milligan                           *)
(*                E|S|C                                    *)
(*                970.925.1700                             *)
(*                                                         *)
(*                11/05/2002                               *)
(***********************************************************)
(*!!FILE REVISION:                                         *)
(*  REVISION DATE: 09/18/2002                              *)
(*                                                         *)
(*  COMMENTS:                                              *)
(*                                                         *)
(***********************************************************)
(*}}PS_SOURCE_INFO                                         *)
(***********************************************************)

(***********************************************************)
(* System Type : Netlinx                                   *)
(***********************************************************)
(* REV HISTORY:                                            *)
(***********************************************************)

(***********************************************************)
(*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
(***********************************************************)
//#DEFINE DEBUG 1
//#DEFINE LINE_DEBUG 1
//#DEFINE VOL_DEBUG 1
//#DEFINE AMP_DEBUG 1
//#DEFINE LEVEL_DEBUG 1
//#DEFINE DIRECT_VOL_DEBUG 1

DEFINE_DEVICE
(***********************************************************)
(*               CONSTANT DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_CONSTANT
cnLevelAMX = 1
cnRCVR_TIMELINE_ID  = 999    // must not be used anywhere else...
LONG cnRCVR_POLL_TIMES[]={1000,1033}

cnResponseHeader    = $02
cnAmpRequest        = $A0
cnTunerRequest      = $A1
cnSoundRequest      = $A3
cnAmpAnswer         = $A8
cnTunerAnswer       = $A9
cnSoundAnswer       = $AB

cnAmpNoExecutable   = $0E
cnAmpNoFunction     = $0F
cnAmpAck            = $FD
cnAmpNAck           = $FE

cnAmpStatus         = $82
cnVolStatus         = $92
cnInputSelect       = $42
cnMuteSet           = $53
cnPowerSet          = $60
cnVolSet            = $52
cn12vTrigger        = $43

cnMainRoom          = $00
cn2ndRoom           = $01
cn3rdRoom           = $02
 `
(***********************************************************)
(*              DATA TYPE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_TYPE

(***********************************************************)
(*               VARIABLE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_VARIABLE
VOLATILE CHAR strRcvrBuff[500]
VOLATILE CHAR strJunk[10]
VOLATILE CHAR strResponseLine[50]

VOLATILE INTEGER nI
VOLATILE INTEGER nLineReady
VOLATILE INTEGER nMuteState = 0
VOLATILE CHAR strDiagRcvrBuff[500]

(***********************************************************)
(*               LATCHING DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_LATCHING

(***********************************************************)
(*       MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW           *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE

(***********************************************************)
(*        SUBROUTINE/FUNCTION DEFINITIONS GO BELOW         *)
(***********************************************************)
(* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
(* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)

(*
 *
 *
 *
 *)
define_function integer CalculateCheckSum( char cInputString[] )
local_var integer nIdx
local_var integer nSum
{
  nSum = 0
  if( length_string(cInputString) > 0 )
  {
    for(nIdx=1; nIdx<=length_string(cInputString); nIdx++ )
    {
      nSum = nSum + cInputString[nIdx]
    }
    nSum = ($100 - nSum) & $FF
    //send_string 0,"'CheckSum = ',itohex(nSum)"
  }
  return (nSum)
}


(* 
 * This function will take the high byte and the low byte of the 
 * receiver volume, and convert it to a scale of 128-256.
 * Actually, since the low byte represents .0 or .5, it's just 
 * being ignored for now.
 * SMM
 *)
define_function float ConvertVolume( char cHighByte, char cLowByte )
local_var float fConvertedVolume
{
  if( cHighByte == $00 )
  {
    cHighByte = $FF
  }
  else
  {
    cHighByte--
  }
  
  fConvertedVolume = (cHighByte - 127)/1.27
  return fConvertedVolume
}

define_call 'MUTE_ON'
local_var integer cCheckSum
{
  cCheckSum = CalculateCheckSum( "$04,$A0,$53,$00,$01" )
  // Turn on Mute
  send_string dvRcvr, "$02,$04,$A0,$53,$00,$01,cCheckSum"

  nMuteState = 1  
}

define_call 'MUTE_OFF'
local_var integer cCheckSum
{
  cCheckSum = CalculateCheckSum( "$04,$A0,$53,$00,$00" )
  // Turn Off Mute
  send_string dvRcvr, "$02,$04,$A0,$53,$00,$00,cCheckSum"

  nMuteState = 0
}

(*
 * MUTUALLY_EXCLUSIVE_CHANNEL_ON
 *    Netlinx has a bug where if you try to use Mutually Exclusive
 *    variables inside a module, 2 things happen.
 *    1) The Mutually won't work
 *    2) It causes the Netlinx processor to lock up most of the time on a reboot.
 *
 * This was wrote as a work around to Mutually Exclusive
 *)
define_call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (INTEGER nChan)
local_var integer nX
{
  for( nX=10;nX<=21;nX++)
  {
    if( nX != nChan )
    {
      off[vdvRcvr,nX]
    }
    else
    {
      on[vdvRcvr,nX]
    }
  }
}

(*
 * Process_Audio_Function() 
 *   This turns on Netlinx channels based on the AudioFunction received.
 *   Allows for easy checking of the receiver current source.
 *
 *)
define_call 'Process_Audio_Function'( char cAudioFunction )
{
  switch( cAudioFunction )
  {
    case $00:   // Tuner
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = TUNER'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (11)
      break
    }
    case $01:   // Phone
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = PHONE'"
    #END_IF  
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (12)
      break
    }
    case $02:   // CD
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = CD'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (10)
      break
    }
    case $03:   // DAT
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = DAT'"
    #END_IF
      break
    }
    case $04:   // MD
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = MD'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (15)
      break
    }
    case $05:   // Tape 1
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = TAPE1'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (14)
      break
    }
    case $06:   // Tape 2
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = TAPE2'"
    #END_IF
      break
    }
    case $07:   // Digital 1
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = DIGITAL1'"
    #END_IF
      break
    }
    case $08:   // Digital 2
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = DIGITAL2'"
    #END_IF
      break
    }
    case $09:   // Digital 3
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = DIGITAL3'"
    #END_IF
      break
    }
    case $0A:   // Aux 1
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = AUX1'"
    #END_IF
      break
    }
    case $0B:   // Aux 2
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = AUX2'"
    #END_IF
      break
    }
    case $0C:   // MD-WM
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = MD-WM'"
    #END_IF
      break
    }
    case $0D:   // MD2
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = MD2'"
    #END_IF
      break
    }
    case $0E:   // MS
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = MS'"
    #END_IF
      break
    }
    case $0F:   // Source
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = SOURCE'"
    #END_IF
      break
    }
    case $10:   // Video 1
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = VIDEO1'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (19)
      break
    }
    case $11:   // Video 2
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = VIDEO2'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (20)
      break
    }
    case $12:   // Video 3
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = VIDEO3'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (21)
      break
    }
    case $13:   // Video 4
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = VIDEO4'"
    #END_IF
      break
    }
    case $14:   // Video 5
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = VIDEO5'"
    #END_IF
      break
    }
    case $15:   // LD
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = LD'"
    #END_IF
      break
    }
    case $16:   // TV
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = TV'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (13)
      break
    }
    case $17:   // DSS
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = DSS'"
    #END_IF
      break
    }
    case $18:   // VCD
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = VCD'"
    #END_IF
      break
    }
    case $19:   // DVD
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = DVD'"
    #END_IF
      call 'MUTUALLY_EXCLUSIVE_CHANNEL_ON' (18)
      break
    }
    case $20:   // 5.1 Input
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = 5.1'"
    #END_IF           
      break     
    }
    case $FE:   // No Select
    {
    #IF_DEFINED AMP_DEBUG
      send_string 0,"'Current Receiver Input = NO SELECT'"
    #END_IF
      break
    }
  }
}

define_call 'DirectVolumeJump'(integer nVolumeLevel)
local_var float fVolume
local_var integer nJumpVolume
local_var integer nCheckSum
local_var char cCommandString[10]
local_var char strJunkLine[50]
{
  // Convert volume scaled from 0-100 into volume
  // scaled from 128-256
  if( fVolume < 10 )
  {
    // once it's below 10, time to zero it out.
    fVolume = 128.0
  }
  else
  {
    fVolume = nVolumeLevel*1.28 + 128
  }
  
  nJumpVolume = type_cast(fVolume)
  
  if( nJumpVolume == $FF )
  {
    nJumpVolume = $00
  }
  else
  {
    // increment the volume to help acount for rounding errors
    nJumpVolume++
  }
  
  cCommandString = "$06,cnAmpRequest,cnVolSet,cnMainRoom,$01,nJumpVolume,$00"
  nCheckSum = CalculateCheckSum( cCommandString )
  cCommandString = "cnResponseHeader,cCommandString,nCheckSum"
  
  #IF_DEFINED DIRECT_VOL_DEBUG  
    clear_buffer strJunkLine
    For (nI=1;nI<=Length_String(cCommandString);nI++)
    {
      strJunkLine = "strJunkLine,ITOHEX(cCommandString[nI]),','"
    }
    send_string 0,"'Direct Vol send line = ',strJunkLine"
  #END_IF
    
  send_string dvRcvr,"cCommandString"
}
 

define_call 'ParseFullLine'
local_var integer nLength
local_var integer nCheckSum
local_var char strJunkLine[50]
{
  // Ensure the line starts with the header.
  while( find_string( strRcvrBuff,"cnResponseHeader",1 ) )
  {
    // remove all characters from the buffer up to the header.
    strJunkLine = remove_string( strRcvrBuff,"cnResponseHeader",1 )
    
    // Get the length
    nLength = strRcvrBuff[1]
    
    // remove all characters from the front to length+1
    if( length_string( strRcvrBuff ) > nLength+1 )
    {                   
      strResponseLine = left_string( strRcvrBuff, nLength+1 )
      strJunkLine = remove_string( strRcvrBuff, strResponseLine, 1)
      
      nCheckSum = 0;
      For (nI=1; nI<=length_string(strResponseLine); nI++)
      {
        nCheckSum = nCheckSum + strResponseLine[nI]
      }
      nCheckSum = ($100-nCheckSum) &$FF

    #IF_DEFINED LINE_DEBUG  
      clear_buffer strJunkLine
      For (nI=1;nI<=Length_String(strResponseLine);nI++)
      {
        strJunkLine = "strJunkLine,ITOHEX(strResponseLine[nI]),','"
      }
      send_string 0,"'New line just parsed = ',strJunkLine"
    #END_IF  
      if (nCheckSum != strRcvrBuff[Length_String(strRcvrBuff)]) // if the checksum fails
      {
        Send_String 0,"'Checksum failed.  Ignoring this line. nCheckSum=',ITOHEX(nCheckSum),' ResponseCheckSum=',ITOHEX(strRcvrBuff[Length_String(strRcvrBuff)])"
      }
      else
      {
        // now we have a good line.
        call 'ProcessReceivedLine'(strResponseLine)
      }
    }
  }
}

define_call 'ProcessReceivedLine'( char strReceivedLine[] )
LOCAL_VAR integer nBytesLeft
LOCAL_VAR CHAR    cCategory
LOCAL_VAR CHAR    cResponseCode
LOCAL_VAR CHAR    cVolHighByte
LOCAL_VAR CHAR    cVolLowByte
LOCAL_VAR CHAR    cAmpZone
LOCAL_VAR CHAR    cAudioFunction
LOCAL_VAR CHAR    cVideoFunction
LOCAL_VAR CHAR    cData1
LOCAL_VAR CHAR    cData2
LOCAL_VAR CHAR    strJunkLine[50]
LOCAL_VAR CHAR    strNewLine[50]
{
  strNewLine = strReceivedLine
  
  // Ensure the line exists
  if( length_string( strNewLine ) <= 0 )
  {
  #IF_DEFINED DEBUG
    send_string 0,"'ProcessReceivedLine -> line length is <= 0'"
  #END_IF
    return
  }
  else
  {
  #IF_DEFINED LINE_DEBUG
    clear_buffer strJunkLine
    For (nI=1;nI<=Length_String(strNewLine);nI++)
    {
      strJunkLine = "strJunkLine,ITOHEX(strNewLine[nI]),','"
    }
    send_string 0,"'Processing a full line!!! = ',strJunkLine"
  #END_IF
  }

  // Byte 1 cnHeader was stripped off before entering ProcessReceivedLine()
    
  // Get the length, store it
  (* Byte 2 *)
  nBytesLeft = strNewLine[1]
  
  // Get the Category
  (* Byte 3 *)
  cCategory = strNewLine[2]
  
  switch ( cCategory )
  {
    case cnAmpAnswer:
    {
      // Get the Response Code
      (* Byte 4 *)
      cResponseCode = strNewLine[3]
      
      switch ( cResponseCode )
      {
        case cnAmpStatus:
        {
        #IF_DEFINED AMP_DEBUG
          send_string 0,"'Received a AMP STATUS line!!!'"
        #END_IF
          // Get the Zone
          (* Byte 5 *)
          cAmpZone = strNewLine[4]         
          
          // Get the currect Audio Function
          (* Byte 6 *)
          cAudioFunction = strNewLine[5]
          
          // Get the Video Function
          (* Byte 7 *)
          cVideoFunction = strNewLine[6]
          
          // Get Data1
          (* Byte 8 *)
          cData1  = strNewLine[7]
          
          // Get Data2
          (* Byte 9 *)
          cData2  = strNewLine[8]
          
          CALL 'Process_Audio_Function'( cAudioFunction )
          
          // CALL 'Process_Amp_Data' ( cData1 )
          // CALL 'Process_Trigger_Data' ( cData2 )
          break
        }
        case cnVolStatus:
        {
          local_var integer nVolumeAMX
        #IF_DEFINED VOL_DEBUG
          //send_string 0,"'Received a VOL STATUS line!!!'"
        #END_IF  
          (* Byte 5 *)
          // not needed since all we're worrying about it Bytes 7 & 8
          (* Byte 6*)
          // not needed since all we're worrying about it Bytes 7 & 8
          
          // Strip off the High Volume byte
          (* Byte 7 *)
          cVolHighByte = strNewLine[6] 
          
          // Strip off the Low Volume byte
          (* Byte 8 *)
          cVolLowByte  = strNewLine[7]
          
          nVolumeAMX = type_cast( ConvertVolume(cVolHighByte, cVolLowByte) )
          
          // Create a level event with the newly converted volume
          send_level vdvRcvr,cnLevelAMX,nVolumeAMX
          break
        }
        case cnAmpNoExecutable:
        {
          send_string 0,"'Receiver was unable to execute command!!!'"
          break
        }
        case cnAmpNoFunction:
        {
          send_string 0,"'Receiver was unable to recognize command!!!'"
          break
        }
        default:
        {
          send_string 0, "'Did not find the Response code: ',itohex(cResponseCode)"
          break
        }
      } // END switch( AmpResponse )   
    } // End Amp Answer Case:
    case cnTunerAnswer:
    {
      break
    }
    case cnSoundAnswer:
    {
      break
    }
    default:
    {
      send_string 0, "'Did not find the Category code: ',itohex(cCategory)"
      break
    }
  } // END switch( category )
}

(***********************************************************)
(*                STARTUP CODE GOES BELOW                  *)
(***********************************************************)
DEFINE_START

(***********************************************************)
(*                THE EVENTS GOES BELOW                    *)
(***********************************************************)
DEFINE_EVENT
DATA_EVENT[dvRcvr]
{
  ONLINE:
  {
    SEND_COMMAND dvRcvr,'SET BAUD 9600,N,8,1 485 DISABLE'
    SEND_COMMAND dvRcvr,'RXON'
    SEND_COMMAND dvRcvr,'HSOFF'
    SEND_COMMAND dvRcvr,'XOFF'
    SEND_STRING 0,'Sony Receiver Online'
    
    // Create the timeline that asks for Volume levels, etc...
    TIMELINE_CREATE(cnRCVR_TIMELINE_ID,cnRCVR_POLL_TIMES,2,TIMELINE_ABSOLUTE,TIMELINE_REPEAT)
  }
  OFFLINE:
  {
    TIMELINE_KILL(cnRCVR_TIMELINE_ID)
    SEND_STRING 0,'Sony Receiver Offline'
  }
  STRING:
  {
    strRcvrBuff = "strRcvrBuff,DATA.TEXT"
    
    CALL 'ParseFullLine'
  }
}

TIMELINE_EVENT[cnRCVR_TIMELINE_ID]
{
  SWITCH(TIMELINE.SEQUENCE)
  {
    CASE 1:
    {
      #if_defined VOL_DEBUG
        send_string 0,"'Sending Vol Status request... $02,$04,$A0,$92,$00,$01,$C9'"
      #end_IF
      send_string dvRcvr,"$02,$04,$A0,$92,$00,$01,$C9" (* Volume Status Request *)
    }
    CASE 2:
    {
    #if_defined AMP_DEBUG
      send_string 0,"'Sending Amp Status request... $02,$03,$A0,$82,$00,$DB'"
    #end_if
      send_string dvRcvr,"$02,$03,$A0,$82,$00,$DB" (* AMP Status Request *)
    }
  }
}


LEVEL_EVENT[vdvRcvr,1]
{
#if_defined LEVEL_DEBUG
  send_string 0,"'LEVEL_EVENT generated:', itoa(level.value)"
#END_IF
}


LEVEL_EVENT[vdvRcvr,2]
{
#if_defined LEVEL_DEBUG
  send_string 0,"'LEVEL_EVENT received:', itoa(level.value)"
#end_if
  call 'DirectVolumeJump'(level.value)  
}

(*********** Below are all discrete send string pushes ********)
Button_Event [vdvRcvr,1] // Volume Up
{
  PUSH:
  {
    call 'MUTE_OFF'
    
    send_string dvRcvr,"$02,$06,$A0,$52,$00,$02,$00,$02,$04"(*Volume Up main zone*)
  }
  HOLD[1,REPEAT]:
  {
    send_string dvRcvr,"$02,$06,$A0,$52,$00,$02,$00,$02,$04"(*Volume Up main zone*)
  }
}

Button_Event [vdvRcvr,2] // Volume Down
{
  PUSH:
  {
    call 'MUTE_OFF'
    
    send_string dvRcvr,"$02,$06,$A0,$52,$00,$02,$FF,$FE,$09"(*Volume Down main zone*)
  }
  HOLD[1,REPEAT]:
  {
    send_string dvRcvr,"$02,$06,$A0,$52,$00,$02,$FF,$FE,$09"(*Volume Down main zone*)
  }
}

Button_Event [vdvRcvr,3] // Mute
{
  PUSH:
  {
    if( !nMuteState )
    { 
      call 'MUTE_ON'
    }
    else
    {
      call 'MUTE_OFF'
    }
  }
}

Button_Event [vdvRcvr,4] // Mute On
{
  PUSH:
  {
    call 'MUTE_ON'
  }
}

Button_Event [vdvRcvr,5] // Mute Off
{
  PUSH:
  {
    call 'MUTE_OFF'
  }
}

Button_Event [vdvRcvr,10]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$02,$18"(*input CD,main-zone*)
  }
}

Button_Event [vdvRcvr,11]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$00,$1A"(*input tuner,main-zone*)
  }
}

Button_Event [vdvRcvr,12]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$01,$19"(*input phono,main-zone*)
  }
}

Button_Event [vdvRcvr,13]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$16,$04"(*input TV,main-zone*)
  }
}

Button_Event [vdvRcvr,14]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$05,$15"(*input TAPE1,main-zone*)
  }
}

Button_Event [vdvRcvr,15]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$04,$16"(*input MD,main-zone*)
  }
}

Button_Event [vdvRcvr,18]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$19,$01"(*input DVD,main-zone*)
  }
}

Button_Event [vdvRcvr,19]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$10,$0A"(*input video1,main-zone*)
  }
}

Button_Event [vdvRcvr,20]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$11,$09"(*input video2,main-zone*)
  }
}

Button_Event [vdvRcvr,21]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$00,$12,$08"(*input video3,main-zone*)
  }
}

Button_Event [vdvRcvr,27]
{
  Push:
  {
    local_var integer cCheckSum
    cCheckSum = CalculateCheckSum( "02,$A0,$21" )
    send_string dvRcvr,"$02,$02,$A0,$21,cCheckSum"(*power on main zone*)
    (*
    WAIT 3
      send_string dvRcvr,"$02,$04,$A0,$60,$00,$01,$FB"(*power on main zone*)
    *)
  }
}

Button_Event [vdvRcvr,28]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A0,$20,$3E"(*power off main zone*)
  }
}

Button_Event [vdvRcvr,30]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$02,$16" (* analog direct *)
  }
}

Button_Event [vdvRcvr,31]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$04,$14" (* cinema studio ex. A *)
  }
}

Button_Event [vdvRcvr,32]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$05,$13" (* cinema studio ex. B *)
  }
}

Button_Event [vdvRcvr,33]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$06,$12" (* cinema studio ex. C *)
  }
}

Button_Event [vdvRcvr,34]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$16,$02" (* jazz club *)
  }
}

Button_Event [vdvRcvr,35]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$00,$18" (* 2ch stereo surround off *)
  }
}

Button_Event [vdvRcvr,36]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$1E,$FA" (* concert hall A, digital concert hall *)
  }
}

Button_Event [vdvRcvr,37]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$1F,$F9" (* concert hall B, digital concert hall *)
  }
}

Button_Event [vdvRcvr,38]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A3,$13,$48"     (* multi ch1 direct *)
  }
}

Button_Event [vdvRcvr,39]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A3,$14,$47"     (* multi ch2 direct *)
  }
}

Button_Event [vdvRcvr,40]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$01,$17" (* auto format decode, auto decoding mode *)
  }
}

Button_Event [vdvRcvr,41]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$03,$15" (* normal surround *)
  }
}

Button_Event [vdvRcvr,42]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$0B,$0D" (* mono movie *)
  }
}

Button_Event [vdvRcvr,43]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$0C,$0C"  (* stereo movie *)
  }
}

Button_Event [vdvRcvr,44]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$15,$03"  (* opera house *)
  }
}

Button_Event [vdvRcvr,45]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$17,$01"  (* disco/club *)
  }
}

Button_Event [vdvRcvr,46]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$19,$FF"  (* live concert *)
  }
}

Button_Event [vdvRcvr,47]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$1C,$FC"  (*  game  *)
  }
}

Button_Event [vdvRcvr,48]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$18,$00"  (* church *)
  }
}

Button_Event [vdvRcvr,49]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$1B,$FD"  (* stadium *)
  }
}

Button_Event [vdvRcvr,50]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$1A,$FE"  (* arena *)
  }
}

Button_Event [vdvRcvr,51]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A3,$09,$52"      (* sound field toggel up +1 *)
  }
}

Button_Event [vdvRcvr,52]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A3,$08,$53"      (* sound field toggel down -1 *)
  }
}

Button_Event [vdvRcvr,70]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$60,$01,$01,$FA"(*power2 on 2nd zone*)
  }
}

Button_Event [vdvRcvr,71]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$60,$01,$00,$FB"(*power2 off 2nd zone*)
  }
}
(*
Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$60,$02,$01,$F9"(*power3 on 3rd zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$60,$02,$00,$FA"(*power3 off 3rd zone*)
  }
}


Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$43,$00,$01,$18"(*12v on_trigger channel 1 *)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$43,$00,$00,$19"(*12v off_trigger channel 1 *)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$43,$01,$01,$17"(*12v on_trigger channel 2 *)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$43,$01,$00,$18"(*12v off_trigger channel 2 *)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$43,$02,$01,$16"(*12v on_trigger channel 3 *)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A0,$43,$02,$00,$17"(*12v off_trigger channel 3 *)
  }
}
*)

(***************** Main Room Inputs to amp ****************************************)

(*note:you can select phono input only from main zone,in order to*)
(*send to 2/3 zones, you have to select "source" on 2/3 input mode*)
(*in order to get phono out. You cannot discretly select phono from*)
(*2/3 input modes as an input. eg:phono may not be playing,no vinal*)
(*Hence:you wont see a command for discrete phono 2/3zone input select*)
(*In this code, I do provide button status feedback of Phono to 2/3 zones*)
(*Remember,its only feedback informing that phono has been sent to 2/3zones*)
(*and therefore "source" had to have been selected as 2/3 discrete input*)
(*There is no command associated with Phono buttons in 2/3 zones as discrete inputs*)

(****************** 2nd room input ****************************)

Button_Event [vdvRcvr,80]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$00,$19"(*input tuner,2nd-zone*)
  }
}

Button_Event [vdvRcvr,81]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$02,$17"(*input CD,2nd-zone*)
  }
}

Button_Event [vdvRcvr,82]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$04,$15"(*input MD,2nd-zone*)
  }
}

Button_Event [vdvRcvr,83]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$05,$14"(*input TAPE1,2nd-zone*)
  }
}

Button_Event [vdvRcvr,84]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$0F,$0A"(*input source,2nd-zone*)
  }
}

Button_Event [vdvRcvr,85]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$10,$09"(*input video1,2nd-zone*)
  }
}

Button_Event [vdvRcvr,86]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$11,$08"(*input video2,2nd-zone*)
  }
}

Button_Event [vdvRcvr,87]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$12,$07"(*input video3,2nd-zone*)
  }
}

Button_Event [vdvRcvr,88]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$16,$03"(*input TV,2nd-zone*)
  }
}

Button_Event [vdvRcvr,89]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$01,$19,$00"(*input DVD,2nd-zone*)
  }
}


(*************** 3rd room inputs ******************************)
(*
Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$00,$18"(*input tuner,3rd-zone*)
  }
}
*)

(***********************************************************)
(* If you send this string you will get return "$FE" nack *)
(* see note in Phono main zone input select for explain   *)
(*
Button_Event [vdvRcvr,]
{
  Push:
  {
    (*send_string dvRcvr,"$02,04,$A0,$42,$02,$01,$17"*)(*input phono,3rd-zone*)
  }
  Release:
  {
  }
}
*)
(***********************************************************)
(*
Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$02,$16"(*input CD,3rd-zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$04,$14"(*input MD,3rd-zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$05,$13"(*input TAPE1,3rd-zone*)
  }
}
(* todo : to put in this button on TP for 3rd zone input select*)

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$0F,$09"(*input source,3rd-zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$10,$08"(*input video1,3rd-zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$11,$07"(*input video2,3rd-zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$12,$06"(*input video3,3rd-zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$16,$02"(*input TV,3rd-zone*)
  }
}

Button_Event [vdvRcvr,]
{
  Push:
  {
    send_string dvRcvr,"$02,04,$A0,$42,$02,$19,$FF"(*input DVD,3rd-zone*)
  }
}
*)

(*************************************************************)


(****************** discrete sends ***************************)

Button_Event [vdvRcvr,100]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$20,$3D" (* FM discrete select *)
  }
}

Button_Event [vdvRcvr,101]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$1f,$3E" (* AM discrete select *)
  }
}

Button_Event [vdvRcvr,102]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$07,$56" (* auto tunining/scan up *)
  }
}

Button_Event [vdvRcvr,103]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$08,$55" (* auto tunining/scan down *)
  }
}

Button_Event [vdvRcvr,104]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$09,$54" (* auto tunining/scan stop *)
  }
}

Button_Event [vdvRcvr,105]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$05,$58" (* manual tunining+ 1mHz/1kHz *)
  }
}

Button_Event [vdvRcvr,106]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$06,$57" (* manual tunining- 1mHz/1kHz *)
  }
}

Button_Event [vdvRcvr,107]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$0B,$52" (* preset channel+  *)
  }
}

Button_Event [vdvRcvr,108]
{
  Push:
  {
    send_string dvRcvr,"$02,02,$A1,$0C,$51" (* preset channel-  *)
  }
}

Button_Event [vdvRcvr,171]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$82,$96"  (* headphone direct *)
  }
}

Button_Event [vdvRcvr,172]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$80,$98"  (* headphone 2ch *)
  }
}

Button_Event [vdvRcvr,173]
{
  Push:
  {
    send_string dvRcvr,"$02,$03,$A3,$42,$83,$95"  (* headphone theater *)
  }
}


Button_Event [vdvRcvr,200]
{
  Push:
  {
    (* time_loop=0 and direct_key=0 are also needed in preset+/-,tune+/- *)
    (* scan+/-/stop,vol+/-/low/med/high,am-fm and mute/on/off            *)
    (*  buttons for the same explain below, end result is fast updates   *)

    (* need to zero a running loop counter that starts when you are direct *)
    (*keying tunning which times out at same rate that receiver times out  *)
    (*zeroing time_loop updateds the frequency for that direct select preset*)
    (*selected on the fly if you are in a direct key tunning process, if not*)
    (*its in its default state already *)
    (*dierect_key=0 is needed so that if you are direct key tunning and touch a*)
    (*discrete tuner preset, you wont be able to use keyed numbers which would *)
    (*if not disabled,goto that current shift preset number which can confuse  *)
    (*accurate feedback as to what is going on durning direct keyed tunning    *)
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$01,$17"
  }
}

Button_Event [vdvRcvr,201]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$02,$16"
  }
}

Button_Event [vdvRcvr,202]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$03,$15"
  }
}

Button_Event [vdvRcvr,203]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$04,$14"
  }
}

Button_Event [vdvRcvr,204]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$05,$13"
  }
}

Button_Event [vdvRcvr,205]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$06,$12"
  }
}

Button_Event [vdvRcvr,206]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$07,$11"
  }
}

Button_Event [vdvRcvr,207]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$08,$10"
  }
}

Button_Event [vdvRcvr,208]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$09,$0F"
  }
}

Button_Event [vdvRcvr,209]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$01,$0A,$0E"
  }
}

Button_Event [vdvRcvr,210]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$01,$16"
  }
}

Button_Event [vdvRcvr,211]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$02,$15"
  }
}

Button_Event [vdvRcvr,212]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$03,$14"
  }
}

Button_Event [vdvRcvr,213]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$04,$13"
  }
}

Button_Event [vdvRcvr,214]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$05,$12"
  }
}

Button_Event [vdvRcvr,215]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$06,$11"
  }
}

Button_Event [vdvRcvr,216]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$07,$10"
  }
}

Button_Event [vdvRcvr,217]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$08,$0F"
  }
}

Button_Event [vdvRcvr,218]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$09,$0E"
  }
}

Button_Event [vdvRcvr,219]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$02,$0A,$0D"
  }
}

Button_Event [vdvRcvr,220]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$01,$15"
  }
}

Button_Event [vdvRcvr,221]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$02,$14"
  }
}

Button_Event [vdvRcvr,222]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$03,$13"
  }
}

Button_Event [vdvRcvr,223]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$04,$12"
  }
}

Button_Event [vdvRcvr,224]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$05,$11"
  }
}

Button_Event [vdvRcvr,225]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$06,$10"
  }
}

Button_Event [vdvRcvr,226]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$07,$0F"
  }
}

Button_Event [vdvRcvr,227]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$08,$0E"
  }
}

Button_Event [vdvRcvr,228]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$09,$0D"
  }
}

Button_Event [vdvRcvr,229]
{
  Push:
  {
    send_string dvRcvr,"$02,$04,$A1,$42,$03,$0A,$0C"
  }
}

Button_Event [vdvRcvr,230]
{
  Push:
  {
    (*time loop is counted down within 'get_tuner_status' which is called*)
    (*every pass through mainline and acted on if correct byte string came back*)
    (*from request specific request was made for current x value *)
    (*this delay var. is regulated to follow recievers time-out *)
    (*when using tuner key direct,as mainline increases soto will this have*)
    (*tobe twikked *)
    send_string dvRcvr,"$02,$02,$A1,$1D,$40"  (* key direct tunning begin *)
//    call 'clear_tuner_string'
  }
}

Button_Event [vdvRcvr,231]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$11,$4C"  (* key direct one for tuner *)
    (*key_tuner_add_string= '1'*)
    //call 'update_tuner_key_direct'(1)
    (*
    if (key_preset=1){
    send_string dvRcvr,"$02,$02,$A1,$11,$4C"
    (* key direct one will also set current shift preset to this discrete set *)
    (* eg: say your on C5, and press this key, it will goto 'C1' *) 
    }
    *)
  }
}

Button_Event [vdvRcvr,232]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$12,$4B"  (* key direct two *)
    (*key_tuner_add_string= '2'*)
    //call 'update_tuner_key_direct'(2)
    (*
    if (key_preset =1){
    send_string dvRcvr,"$02,$02,$A1,$12,$4B"  (* key direct two *)
    (* key direct one will also set current shift preset to this discrete set *)
    (* eg: say your on C5, and press this key, it will goto 'C1' *)
    } *)
  }
}

Button_Event [vdvRcvr,233]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$13,$4A"  (* key direct three *)
    (*key_tuner_add_string= '3'*)
    //call 'update_tuner_key_direct'(3)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
    (*
    if (key_preset=1){
    send_string dvRcvr,"$02,$02,$A1,$13,$4A"  (* key direct three *)
    }*)
  }
}

Button_Event [vdvRcvr,234]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$14,$49"  (* key direct four *)
    (*key_tuner_add_string= '4'*)
    //call 'update_tuner_key_direct'(4)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
  }
}

Button_Event [vdvRcvr,235]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$15,$48"  (* key direct five *)
    (*key_tuner_add_string= '5'*)
    //call 'update_tuner_key_direct'(5)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
  }
}

Button_Event [vdvRcvr,236]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$16,$47"  (* key direct six *)
    (*key_tuner_add_string= '6'*)
    //call 'update_tuner_key_direct'(6)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
  }
}

Button_Event [vdvRcvr,237]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$17,$46"  (* key direct seven *)
    (*key_tuner_add_string= '7'*)
    //call 'update_tuner_key_direct'(7)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
  }
}

Button_Event [vdvRcvr,238]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$18,$45"  (* key direct eight *)
    (*key_tuner_add_string= '8'*)
    //call 'update_tuner_key_direct'(8)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
  }
}

Button_Event [vdvRcvr,239]
{
  Push:
  {
    send_string dvRcvr,"$02,$02,$A1,$19,$44"  (* key direct nine *)
    (*key_tuner_add_string= '9'*)
    //call 'update_tuner_key_direct'(9)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
  }
}

Button_Event [vdvRcvr,240]
{
  push:
  {
    send_string dvRcvr,"$02,$02,$A1,$10,$4D"  (* key direcdt zero *)
    (*key_tuner_add_string= '0'*)
    //call 'update_tuner_key_direct'(0)
    (*send_command TP,"'TEXT 2-',tuner_string"*)
  }
}

Button_Event [vdvRcvr,241]
{
  push:
  {
    send_string dvRcvr,"$02,$02,$A1,$1A,$43"  (* key shift preset A_ *)
  }
}

Button_Event [vdvRcvr,242]
{
  push:
  {
    send_string dvRcvr,"$02,$02,$A1,$1B,$42"  (* key shift preset B_ *)
  }
}

Button_Event [vdvRcvr,243]
{
  push:
  {
    send_string dvRcvr,"$02,$02,$A1,$1C,$41"  (* key shift preset C_ *)
  }
}


(***********************************************************)
(*            THE ACTUAL PROGRAM GOES BELOW                *)
(***********************************************************)
DEFINE_PROGRAM

(***********************************************************)
(*                     END OF PROGRAM                      *)
(*        DO NOT PUT ANY CODE BELOW THIS COMMENT           *)
(***********************************************************)

